package com.apimanage.auth.service.impl;

import com.apimanage.common.utils.JwtTokenUtil;
import com.apimanage.common.dto.AuthDTO;
import com.apimanage.common.dto.UserDTO;
import com.apimanage.common.exception.ApiException;
import com.apimanage.common.service.AuthService;
import com.apimanage.common.service.UserCenterService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 认证服务实现类
 * 作为Dubbo提供者，实现对外暴露的认证服务接口
 *
 * @author API管理平台
 */
@DubboService
public class AuthServiceImpl implements AuthService {

    // 注入UserCenterService服务（通过Dubbo引用）
    // 设置check=false，避免因为user-center服务不可用而导致auth-center启动失败
    @DubboReference(check = false, timeout = 3000)
    private UserCenterService userService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 使用静态方法调用统一的JWT工具类，无需注入

    @Autowired
    private PasswordEncoder passwordEncoder;

    // Redis中存储黑名单token的前缀
    private static final String REDIS_KEY_PREFIX = "auth:blacklist:";

    @Override
    public Map<String, Object> register(AuthDTO authDTO) {
        try {
            // 检查用户是否已存在
            UserDTO existingUserDTO = userService.getUserByUsername(authDTO.getUsername());
            if (existingUserDTO != null) {
                throw new ApiException(400, "用户名已存在");
            }

            // auth-center负责密码加密
            String encodedPassword = passwordEncoder.encode(authDTO.getPassword());
            AuthDTO encryptedAuthDTO = new AuthDTO();
            encryptedAuthDTO.setUsername(authDTO.getUsername());
            encryptedAuthDTO.setPassword(encodedPassword);
            encryptedAuthDTO.setEmail(authDTO.getEmail());
            encryptedAuthDTO.setPhone(authDTO.getPhone());
            encryptedAuthDTO.setRole("user"); // 设置默认角色

            // 使用专门为auth-center设计的注册方法，直接传递加密后的密码
            boolean success = userService.registerWithAuthDTO(encryptedAuthDTO);
            if (!success) {
                throw new ApiException(500, "注册失败，请重试");
            }

            // 返回注册成功信息
            Map<String, Object> result = new HashMap<>();
            result.put("code", 200);
            result.put("message", "注册成功");
            return result;
        } catch (Exception e) {
            // 捕获所有异常并转换为ApiException
            if (e instanceof ApiException) {
                throw e; // 如果已经是ApiException，直接抛出
            } else {
                // 其他异常统一转换为ApiException
                throw new ApiException(500, "注册失败，请稍后重试");
            }
        }
    }

    @Override
    public boolean validateToken(String token) {
        if (token == null) {
            return false;
        }

        // 检查token是否在黑名单中
        if (redisTemplate.hasKey(REDIS_KEY_PREFIX + token)) {
            return false;
        }

        // 使用JWT工具类验证token
        return JwtTokenUtil.validateToken(token);
    }

    @Override
    public UserDTO validateTokenAndGetUserInfo(String token) {
        if (!validateToken(token)) {
            throw new ApiException(401, "token无效或已过期");
        }

        try {
            // 使用JWT工具类获取用户信息
            UserDTO userDTO = JwtTokenUtil.getUserInfoFromToken(token);
            if (userDTO != null) {
                // 通过user-center服务获取完整用户信息
                return userService.getUserByUsername(userDTO.getUsername());
            }
            throw new ApiException(401, "用户信息不存在");
        } catch (Exception e) {
            throw new ApiException(401, "获取用户信息失败");
        }
    }

    @Override
    public void addToBlacklist(String token, long expireTime) {
        if (token != null) {
            redisTemplate.opsForValue().set(REDIS_KEY_PREFIX + token, true, expireTime, TimeUnit.MILLISECONDS);
        }
    }
}